package com.myk.game.gobangchess.rooms.oldrooms;

import com.myk.game.gobangchess.CustomBottom;
import com.myk.game.gobangchess.Player;
import com.myk.game.gobangchess.RobotPlayer;
import com.myk.game.gobangchess.constants.ColorCost;
import com.myk.game.gobangchess.constants.Msger;
import com.myk.game.gobangchess.rooms.absrooms.AbsAiRoom;
import com.myk.game.gobangchess.signs.*;
import com.myk.game.gobangchess.utils.GridsUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 《黑白逆界》单人pve生存游戏
 */
public class BWAntiSpaceOldRoom extends AbsAiRoom {

    //++for循环+sleep改成递归加Timer
    //++ Game类中的逻辑全都放到Helper中，game仅仅只是个实体类

    //房间工具代码的封装类
    private final RoomHelper helper;
    //一整个游戏环境，点击开始游戏会生成新，每个用户能在后台保留一个存档
    private Game game;

    public BWAntiSpaceOldRoom(String roomName) {
        super(roomName, "单人生存游戏，收集道具，击杀怪物，在不断生成的怪物潮中尽可能的生存下去！", "黑白逆界", GridsUtils.createEmptyGrids(15, 15), true, false);
        helper = new RoomHelper(this);
    }

    /**
     * 房间环境需要的辅助代码的封装
     */
    private static class RoomHelper{
        private final BWAntiSpaceOldRoom room;

        public RoomHelper(BWAntiSpaceOldRoom room) {
            this.room = room;
        }

        /**
         * 获取真人玩家对象
         */
        public Player getHumanPlayer(){
            if (room.player_black instanceof RobotPlayer){
                return room.player_white;
            }
            if (room.player_white instanceof RobotPlayer){
                return room.player_black;
            }
            return null;
        }

        /**
         * 通知真人玩家行动
         */
        public void noticeHumanMove() {
            if (room.player_black instanceof RobotPlayer){
                room.noticeWhiteMove();
            }
            if (room.player_white instanceof RobotPlayer){
                room.noticeBlackMove();
            }
        }

        /**
         * 通知ai行动
         */
        public void noticeRobotMove() {
            if (room.player_black instanceof RobotPlayer){
                room.noticeBlackMove();
            }
            if (room.player_white instanceof RobotPlayer){
                room.noticeWhiteMove();
            }
        }

        /**
         * 显示信息对话框
         */
        public void showInfoDialog(String info) {
            Player player = getHumanPlayer();
            if (player != null){
                player.sendMessage(Msger.showInfoDialog, info);
            }
        }

        /**
         * 获取场上一个随机的空格
         */
        public int[] getRandomEmptyPosition(){
            List<int[]> emptyPositionList = new ArrayList<>();
            for (int i = 0; i < room.curGrids.length; i++) {
                for (int j = 0; j < room.curGrids[0].length; j++) {
                    if (room.curGrids[i][j] == 0){
                        emptyPositionList.add(new int[]{i,j});
                    }
                }
            }
            if (emptyPositionList.size() == 0){
                return null;
            }
            else {
                return emptyPositionList.get((int)(Math.random() * emptyPositionList.size()));
            }
        }

        /**
         * 获取棋盘边缘一个随机的空格
         */
        public int[] getRandomBoardSideEmptyPosition(){
            List<int[]> emptyPositionList = new ArrayList<>();
            for (int i = 0; i < room.curGrids.length; i++) {
                for (int j = 0; j < room.curGrids[0].length; j++) {
                    if (room.curGrids[i][j] == 0){
                        if (i == 0 || i == room.curGrids.length-1 || j == 0 || j == room.curGrids[0].length-1){
                            emptyPositionList.add(new int[]{i,j});
                        }
                    }
                }
            }
            if (emptyPositionList.size() == 0){
                return null;
            }
            else {
                return emptyPositionList.get((int)(Math.random() * emptyPositionList.size()));
            }
        }

        /**
         * 判断该点是否在棋盘内
         */
        public boolean isInGrids(int row, int col) {
            return row >= 0 && row < room.curGrids.length && col >= 0 && col < room.curGrids[0].length;
        }

        /**
         * 获取两个坐标之间的距离长度
         */
        private int getDistance(int row1, int col1, int row2, int col2){
            return Math.abs(row1 - row2) + Math.abs(col1 - col2);
        }

        /**
         * 获取指定坐标，指定格子数可到达的范围集合，不能越过阻挡
         */
        public List<int[]> getCanMovedPos(int row, int col, int sp) {
            List<int[]> canMovedPosList = new ArrayList<>();
            int[] originPoint = new int[]{row, col};
            canMovedPosList.add(originPoint); //原位置也能落下
            int dis = 1;
            while (dis <= sp) { //由原位置向外扩展搜索三次
                moveSearch(originPoint, canMovedPosList, dis);
                dis++;
            }
            canMovedPosList.remove(originPoint); //最后再去除原位置
            return duplicateList(canMovedPosList); //去重后返回
        }

        //移动路径搜索
        private void moveSearch(int[] target, List<int[]> canMovedPosList, int dis) {
            List<int[]> addList = new ArrayList<>();
            for (int[] ints : canMovedPosList) {
                if (getDistance(target, ints) == dis - 1) { //只有最外面一圈的有资格扩展
                    List<int[]> aroundList = getAroundList(ints); //获取每个格子周围一圈的格子
                    for (int[] ints1 : aroundList) {
                        if (isInGrids(ints1[0],ints1[1]) && getDistance(target, ints1) == dis && room.curGrids[ints1[0]][ints1[1]] == 0) { //再把不符合要求的格子排除掉
                            addList.add(ints1);
                        }
                    }
                }
            }
            canMovedPosList.addAll(addList);
        }

        //去除List列表中重复值方法一：普通的方法,利用for循环去重
        private List<int[]> duplicateList(List<int[]> list) {
            for (int i = 0; i < list.size() - 1; i++) {
                for (int j = list.size() - 1; j > i; j--) {
                    int[] item = list.get(i);
                    int[] jtem = list.get(j);
                    if (item[0] == jtem[0] && item[1] == jtem[1]) {
                        list.remove(j);
                    }
                }
            }
            return list;
        }

        //获取某个格子坐标四周的格子坐标列表 （不管是否超出棋盘外）
        private List<int[]> getAroundList(int[] ints) {
            List<int[]> aroundList = new ArrayList<>();
            aroundList.add(new int[]{ints[0] - 1, ints[1]});
            aroundList.add(new int[]{ints[0] + 1, ints[1]});
            aroundList.add(new int[]{ints[0], ints[1] - 1});
            aroundList.add(new int[]{ints[0], ints[1] + 1});
            return aroundList;
        }

        //获取两个坐标之间的距离长度
        private int getDistance(int[] target, int[] ints) {
            return Math.abs(target[0] - ints[0]) + Math.abs(target[1] - ints[1]);
        }

    }

    @Override
    public String getRuleText() {
        return "暂未编写";
    }

    @Override
    protected void onStartPrepare() {
        Player humanPlayer = helper.getHumanPlayer();
        if (humanPlayer != null){
            CustomBottom saveFile = new CustomBottom(this, "保存存档", (player1) -> {
                if (getCurPlayer() == humanPlayer){
                    humanPlayer.sendMessage(Msger.broadcast,"保存存档后期再实现");
                }
            });
            CustomBottom startGame = new CustomBottom(this, "开始游戏", (player) -> {
                humanPlayer.clearCustomBottom();
                //humanPlayer.registerCustomBottom(saveFile);
                humanPlayer.dispatchCustomBottom();
                game = new Game(this);
                game.start();
            });
            CustomBottom loadFile = new CustomBottom(this, "加载存档", (player) -> {
                humanPlayer.sendMessage(Msger.broadcast,"加载存档功能后期再实现");
            });
            humanPlayer.registerCustomBottom(startGame);
            //humanPlayer.registerCustomBottom(loadFile);
        }
    }

    @Override
    public void doOver(int winMode, String winMsg) {
        game = null; //游戏结束了记得清除game
        super.doOver(winMode, winMsg);
    }

    @Override
    public void doRule(int row, int col, int value) {
        if (game != null){
            game.doRule(row, col); //让当前游戏逻辑去处理玩家的点击操作
        }
    }

    @Override
    public String getGameInfo() {
        curGrids = GridsUtils.copyGrids(originGrids);
        signList.clear();
        //没有开始游戏的时候显示海报页面
        if (game == null){
            signList.add(new GroundSign(getIndex(0,0),getIndex(curGrids.length-1,curGrids[0].length-1), ColorCost.BLACK, ColorCost.BLUE_BOARD_LINE, 5f));
            signList.add(new TitleSign(0.5f,0.45f,0,"黑白逆界",ColorCost.WHITE,2f));
        }
        //游戏进行中让游戏自己去绘制
        else {
            game.render();
        }
        return super.getGameInfo();
    }

    @Override
    public String getCoordMode() {
        return "00000000"; //不显示坐标
    }

    @Override
    protected Player createRobotPlayer() {
        return new RobotPlayer(this, "jk123456bwnj", "#逆界", () -> {
            sleep(100);
            game.update();
        });
    }

    /**
     * 游戏专用常量
     */
    public interface GameValue {
        String COLOR_TRANSPARENT = "#00000000"; //透明色
        String COLOR_BLACK = "#000000"; //纯黑色
        String COLOR_WHITE = "#ffffff"; //纯白色
        String COLOR_RED = "#ff0000"; //纯红色
        String COLOR_BLUE = "#0000ff"; //纯蓝色
        String COLOR_YELLOW = "#ffff00"; //纯黄色
        String COLOR_GREEN = "#00ff00"; //纯绿色
        String COLOR_GREEN_LIGHT = "#6600ff00";  //淡绿色
        String COLOR_YELLOW_LIGHT = "#66ffff00";  //淡黄色
        String COLOR_RED_LIGHT = "#66ff0000"; //淡红色

        String COLOR_GRAY_LIGHT = "#33666666";//淡灰色
    }

    /**
     * 游戏状态辅助方法的封装
     */
    private static class GameHelper{
        private final BWAntiSpaceOldRoom room;
        private final Game game;

        public GameHelper(BWAntiSpaceOldRoom room, Game game) {
            this.room = room;
            this.game = game;
        }

        /**
         * 判断指定位置是否为空格
         */
        public boolean isEmptyPos(int row, int col){
            return room.curGrids[row][col] == 0;
        }

        /**
         * 获取一个随机的棋盘边缘空位置
         */
        public int[] getRandomBoardSideEmptyPosition() {
            return room.helper.getRandomBoardSideEmptyPosition();
        }

        /**
         * 获取场上所有棋子集合
         */
        public List<BasePiece> getAllFieldPieces(){
            List<BasePiece> allPieces = new ArrayList<>();
            if (game.fieldMonsterList != null){
                allPieces.addAll(game.fieldMonsterList);
            }
            if (game.fieldPropList != null){
                allPieces.addAll(game.fieldPropList);
            }
            if (game.human != null){
                allPieces.add(game.human);
            }
            return allPieces;
        }

        /**
         * 获取场上所有怪物，并根据它们离主角的距离进行排序
         */
        public List<BaseMonsterPiece> getAllMonsterPiecesAndSort() {
            List<BaseMonsterPiece> monsterList = new ArrayList<>(game.fieldMonsterList);
            monsterList.sort((o1, o2) -> {
                int dis1 = Math.abs(o1.row - game.human.row) + Math.abs(o1.col - game.human.col);
                int dis2 = Math.abs(o2.row - game.human.row) + Math.abs(o2.col - game.human.col);
                return dis1 - dis2;
            });
            return monsterList;
        }

        /**
         * 获取指定位置的棋子 (有可能为空)
         */
        public BasePiece getPieceByPos(int row, int col) {
            for (BasePiece piece : getAllFieldPieces()) {
                if (piece.row == row && piece.col == col){
                    return piece;
                }
            }
            return null;
        }

        /**
         * 获取指定位置的怪物 (有可能为空)
         */
        public BaseMonsterPiece getMonsterByPos(int row, int col) {
            for (BaseMonsterPiece monster : game.fieldMonsterList) {
                if (monster.row == row && monster.col == col){
                    return monster;
                }
            }
            return null;
        }

        /**
         * 通知玩家操作
         */
        public void noticeHumanAction(String tipMsg) {
            room.gameTip = tipMsg;
            room.helper.noticeHumanMove();
        }

        /**
         * 通知ai机器人操作
         */
        public void noticeRobotAction() {
            game.liveDay += 1; //存活天数加1
            room.helper.noticeRobotMove();
        }

        /**
         * 显示棋子详细信息
         */
        public void showPieceInfo(IGameInformation piece) {
            room.helper.showInfoDialog(piece.getInformation());
        }

        /**
         * 获取棋盘行数
         */
        public int getRowCount() {
            return room.curGrids.length;
        }

        /**
         * 获取棋盘列数
         */
        public int getColCount() {
            return room.curGrids[0].length;
        }
    }

    /**
     * 游戏状态实体
     */
    private static class Game{
        private transient GameHelper helper; //工具方法封装类（不参与序列化，反射生成后在注射进去）
        private List<BaseMonsterPiece> fieldMonsterList; //场上怪物集合
        private List<BasePropPiece> fieldPropList; //场上道具集合
        private Human human; //场上的主角
        private long killCount; //击杀怪物数量
        private long liveDay; //存活天数

        public Game(BWAntiSpaceOldRoom room) {
            helper = new GameHelper(room, this);
        }

        //游戏开始时随机初始化地图上的棋子
        private void makeStartPiecesRandom(){
            //++用特定的算法生成墙壁，或者从初始地形表里随机生成
            //随机生成10个怪物
            for (int i = 0; i < 10; i++) {
                this.makeMonsterRandom();
            }
        }

        //随机生成一个怪物棋子
        private void makeMonsterRandom() {
            //获取一个棋盘边缘的随机空格
            int[] rdmPos = helper.getRandomBoardSideEmptyPosition();
            if (rdmPos != null){
                //5分之一的几率召唤暴徒
                if (Math.random() < 0.2){
                    fieldMonsterList.add(new MonsterBT(this, rdmPos[0], rdmPos[1]));
                    helper.room.curGrids[rdmPos[0]][rdmPos[1]] = 7;
                }
                //默认召唤丘林
                else {
                    fieldMonsterList.add(new MonsterQL(this, rdmPos[0], rdmPos[1]));
                    helper.room.curGrids[rdmPos[0]][rdmPos[1]] = 7;
                }
            }
        }

        //指定位置创建玩家棋子
        private void makeHumanConfirm(int row, int col) {
            //指定位置为空地时
            if (helper.isEmptyPos(row,col)){
                //生成玩家棋子
                human = new Human(this,row, col);
                //通知ai机器人操作
                helper.noticeRobotAction();
            }
        }

        /**
         * 游戏开始初始化
         */
        public void start() {
            this.fieldMonsterList = new ArrayList<>();
            this.fieldPropList = new ArrayList<>();
            this.makeStartPiecesRandom();
            helper.noticeHumanAction("请选择你的出生点");
        }

        /**
         * 玩家点击棋盘解析
         */
        public void doRule(int row, int col) {
            //玩家不存在的时候指定位置创建玩家
            if (human == null){
                makeHumanConfirm(row,col);
            }
            //玩家棋子存在时
            else {
                //玩家棋子移动或者攻击完成后
                if (human.moveOrAttack(row,col)){
                    //通知ai机器人操作
                    helper.noticeRobotAction();
                }
                //点击的位置不能移动的话
                else {
                    //弹窗点击到的棋子的详细信息
                    BasePiece piece = helper.getPieceByPos(row,col);
                    if (piece instanceof IGameInformation){
                        helper.showPieceInfo((IGameInformation) piece);
                    }
                }
            }
        }

        /**
         * 游戏流程驱动
         */
        public void update() {
            //获取场上所有怪物，再根据它们离主角的距离进行排序
            List<BaseMonsterPiece> monsterList = helper.getAllMonsterPiecesAndSort();
            //怪物数量少于50的时候随机生成1-2只怪物
            if (fieldMonsterList.size() < 50){
                for (int i = 0; i < (int)(Math.random() * 2) + 1; i++) {
                    makeMonsterRandom();
                }
            }
            //新召唤的怪物除外，其他所有怪物行动
            for (BaseMonsterPiece monster : monsterList) {
                helper.room.sleep(100);
                monster.updateSelf();
                helper.room.noticeAllRefreshGameInfo();
            }

            //切换玩家移动 //++如果玩家没有死的话，如果玩家死了，那就谁都不能移动，分发按钮给玩家
            if (human.hp <= 0){
                human = null;
                helper.room.gameTip = "你已死亡";
                helper.room.helper.noticeHumanMove();
            }
            else {
                helper.noticeHumanAction("等待玩家行动");
            }
        }

        /**
         * 游戏画面渲染
         */
        public void render() {
            //++根据状态渲染棋盘背景
            //渲染棋盘上所有的棋子
            helper.getAllFieldPieces().forEach(BasePiece::renderSelf);
            //++渲染存活天书和击杀怪物数量
        }

    }

    /**
     * 棋子信息获取接口
     */
    private interface IGameInformation{
        /**
         * 获取棋子信息
         */
        String getInformation();
    }

    /**
     * 公共棋子基类
     */
    private abstract static class BasePiece {

        protected Game game;
        protected String name;
        protected int row;
        protected int col;

        public BasePiece(Game game, String name, int row, int col) {
            this.game = game;
            this.name = name;
            this.row = row;
            this.col = col;
        }

        /**
         * 获取坐标数组封装
         */
        public int[] getPosition() {
            return new int[]{row, col};
        }

        /**
         * 获取坐标索引
         */
        public Integer getIndex(){
            return game.helper.room.getIndex(row, col);
        }

        /**
         * 自定义渲染
         */
        public abstract void renderSelf();
    }

    /**
     * 棋子-中立生物基类
     */
    private abstract static class BaseNeutralPiece extends BasePiece {

        public BaseNeutralPiece(Game game, String name, int row, int col) {
            super(game, name, row, col);
        }
    }

    /**
     * 棋子-怪物基类
     */
    private abstract static class BaseMonsterPiece extends BasePiece {

        protected int hp; //生命值
        protected int atk;//攻击力
        protected boolean isNewAppear; //是否新出现的
        protected int[] recentMovePath; //最近一次移动路径
        protected int[] recentAttackPath; //最近一次攻击路径

        public BaseMonsterPiece(Game game, String name, int row, int col) {
            super(game,name, row, col);
            isNewAppear = true;
        }

        //自身是否与humanPiece相邻
        public boolean isAdjacentToPiece(BasePiece piece){
            if (this.col == piece.col){
                return Math.abs(this.row - piece.row) == 1;
            }
            else if (this.row == piece.row){
                return Math.abs(this.col - piece.col) == 1;
            }
            return false;
        }

        //移动行为
        protected void move(int row, int col) {
            game.helper.room.curGrids[this.row][this.col] = 0;
            int oldPos = game.helper.room.getIndex(this.row, this.col);
            this.row = row;
            this.col = col;
            game.helper.room.curGrids[row][col] = 7;
            int newPos = game.helper.room.getIndex(row, col);
            this.recentMovePath = new int[]{oldPos, newPos};
            this.recentAttackPath = null;
            this.isNewAppear = false;
        }

        //攻击行为
        protected void attack(Human human) {
            human.hp -= this.atk;
            int fromPos = game.helper.room.getIndex(this.row, this.col);
            int toPos = game.helper.room.getIndex(human.row, human.col);
            this.recentAttackPath = new int[]{fromPos, toPos};
            this.recentMovePath = null;
            this.isNewAppear = false;
        }

        @Override
        public void renderSelf() {
            //绘制棋子底座
            game.helper.room.curGrids[row][col] = 7;
            //新出生绘制
            if (isNewAppear){
                game.helper.room.signList.add(new BadgeSign(game.helper.room.getIndex(row,col),  "新", 7, GameValue.COLOR_RED, ColorCost.TRANSPARENT));
            }
            //绘制名称
            game.helper.room.signList.add(new TitleSign((col + 0.5f) / game.helper.room.curGrids[0].length, (row + 0.5f) / game.helper.room.curGrids.length, 0, name, GameValue.COLOR_BLACK, 0.3f));
            //绘制生命值
            game.helper.room.signList.add(new BadgeSign(game.helper.room.getIndex(row,col),  hp + "", 1, GameValue.COLOR_GREEN, ColorCost.TRANSPARENT));
            //绘制移动路径
            if (recentMovePath != null){
                game.helper.room.signList.add(new LineSign(recentMovePath[0], recentMovePath[1], GameValue.COLOR_GRAY_LIGHT, 1));
            }
            //绘制攻击路径
            if (recentAttackPath != null){
                game.helper.room.signList.add(new LineSign(recentAttackPath[0], recentAttackPath[1], GameValue.COLOR_RED_LIGHT, 1));
            }
        }

        /**
         * 怪物自己简单思考进行行动
         */
        public abstract void updateSelf();

    }

    /**
     * 棋子-道具基类
     */
    private abstract static class BasePropPiece extends BasePiece {

        protected boolean getAble; //是否能被获取

        public BasePropPiece(Game game, String name, int row, int col) {
            super(game, name, row, col);
        }
    }

    /**
     * 棋子-主角
     */
    private static class Human extends BasePiece implements IGameInformation{

        protected int hp; //生命值
        protected int atk; //攻击力
        protected int sp; //移动距离

        public Human(Game game, int row, int col) {
            super(game, "你",row, col);
            this.hp = 50;
            this.atk = 5;
            this.sp = 2;
        }

        @Override
        public String getInformation() {
            return "\t\t【主角】\n" +
                    "生命值："+hp+"\n" +
                    "攻击力："+atk+"\n" +
                    "移动距离："+sp+"\n";
        }

        @Override
        public void renderSelf() {
            //绘制棋子底座
            game.helper.room.curGrids[row][col] = 1;
            //绘制名称
            game.helper.room.signList.add(new TextSign(game.helper.room.getIndex(row,col), "你", GameValue.COLOR_WHITE));
            //绘制生命值
            game.helper.room.signList.add(new BadgeSign(game.helper.room.getIndex(row,col),  hp + "", 0, GameValue.COLOR_BLUE, GameValue.COLOR_TRANSPARENT));
            //绘制攻击值
            game.helper.room.signList.add(new BadgeSign(game.helper.room.getIndex(row,col),  atk + "", 2, GameValue.COLOR_RED, GameValue.COLOR_TRANSPARENT));

            //当前处于玩家行动时
            if (game.helper.room.getCurPlayer() == game.helper.room.helper.getHumanPlayer()){
                //绘制移动路径
                for (Integer index : getMoveRang()) {
                    game.helper.room.signList.add(new ColorSign(index, GameValue.COLOR_GREEN_LIGHT));
                }
                //绘制攻击路径
                for (Integer index : getAttackRang()) {
                    game.helper.room.signList.add(new ColorSign(index, GameValue.COLOR_YELLOW_LIGHT));
                }
            }
        }

        public boolean moveOrAttack(int row, int col) {
            //移动判断
            if (getMoveRang().contains(game.helper.room.getIndex(row, col))){
                game.helper.room.curGrids[this.row][this.col] = 0;
                this.row = row;
                this.col = col;
                game.helper.room.curGrids[this.row][this.col] = 1;
                return true;
            }
            //攻击判断
            BaseMonsterPiece monster = game.helper.getMonsterByPos(row, col);
            if (monster != null && getAttackRang().contains(game.helper.room.getIndex(row, col))){
                monster.hp -= this.atk;
                if (monster.hp <= 0){
                    game.fieldMonsterList.remove(monster);
                    game.killCount++;
                }
                return true;
            }
            return false;
        }

        public List<Integer> getMoveRang(){
            List<Integer> moveRang = new ArrayList<>();
            List<int[]> posList = game.helper.room.helper.getCanMovedPos(this.row,this.col,this.sp);
            for (int[] pos : posList) {
                moveRang.add(game.helper.room.getIndex(pos[0], pos[1]));
            }
            return moveRang;
        }

        //获取攻击范围
        public List<Integer> getAttackRang(){
            List<Integer> attackRang = new ArrayList<>();
            List<int[]> posList = new ArrayList<>();
            posList.add(new int[]{row, col-1});
            posList.add(new int[]{row, col+1});
            posList.add(new int[]{row-1, col});
            posList.add(new int[]{row+1, col});
            posList.add(new int[]{row-1, col-1});
            posList.add(new int[]{row-1, col+1});
            posList.add(new int[]{row+1, col-1});
            posList.add(new int[]{row+1, col+1});
            posList.removeIf(pos -> !game.helper.room.helper.isInGrids(pos[0], pos[1]));
            posList.removeIf(pos -> game.helper.room.curGrids[pos[0]][pos[1]] != 7);
            for (int[] pos : posList) {
                attackRang.add(game.helper.room.getIndex(pos[0], pos[1]));
            }
            return attackRang;
        }
    }

    /**
     * 棋子-中立生物-狗
     */
    private static class NeutralDog extends BaseNeutralPiece implements IGameInformation{

        public NeutralDog(Game game, String name, int row, int col) {
            super(game, name, row, col);
        }

        @Override
        public void renderSelf() {

        }

        @Override
        public String getInformation() {
            return "【中立生物-狗】";
        }
    }

    /**
     * 棋子-怪物-丘林
     */
    private static class MonsterQL extends BaseMonsterPiece  implements IGameInformation{
        public MonsterQL(Game game,int row, int col) {
            super(game,"丘林", row, col);
            this.hp = 10;
            this.atk = 5;
        }

        @Override
        public void updateSelf() {
            //玩家在攻击范围内，1/4的几率进行攻击
            if (Math.random() < 0.25 && isAdjacentToPiece(game.human)){
                this.attack(game.human);
                return;
            }
            //玩家在视野范围内，优先朝着玩家移动
            if (isInView(game.human) && !isAdjacentToPiece(game.human)){
                int[] moveDir = getMoveDir(game.human);
                //丘林只能直走1格，如果给定方向是斜走的化，随机一个移动方向变为0
                dirStraightness(moveDir);
                this.move(this.row + moveDir[0],  this.col + moveDir[1]);
                return;
            }
            //暴徒在视野内，优先朝着暴徒移动
            MonsterBT bt = getNearestBtInView();
            if (bt != null && !isAdjacentToPiece(bt)){
                int[] moveDir = getMoveDir(bt);
                dirStraightness(moveDir);
                this.move(this.row + moveDir[0],  this.col + moveDir[1]);
                return;
            }
            //随机游走
            moveRandom();
        }

        //目标棋子在自己的视野范围内
        public boolean isInView(BasePiece piece){
            return game.helper.room.helper.getDistance(this.row,this.col, piece.row, piece.col) <= 4;
        }

        //移动方向直向化
        private static void dirStraightness(int[] moveDir) {
            if (moveDir[0] !=0 && moveDir[1] != 0){
                if (Math.random() > 0.5) {
                    moveDir[0] = 0;
                }
                else {
                    moveDir[1] = 0;
                }
            }
        }

        //获取视野范围内最近的暴徒
        private MonsterBT getNearestBtInView() {
            int vp = 4; //视野距离
            int minDistance = Integer.MAX_VALUE;
            MonsterBT nearestBt = null;
            for (BaseMonsterPiece monster : game.fieldMonsterList) {
                if (monster instanceof MonsterBT){
                    int dis = game.helper.room.helper.getDistance(this.row,this.col, monster.row, monster.col);
                    if (dis <= vp && dis < minDistance){
                        minDistance = dis;
                        nearestBt = (MonsterBT) monster;
                    }
                }
            }
            return nearestBt;
        }


        //根据目标棋子获取移动方向
        public int[] getMoveDir(BasePiece piece) {
            int[] dir = new int[]{0,0};
            if (piece.row > this.row){
                dir[0] = 1;
            }else if (piece.row < this.row){
                dir[0] = -1;
            }
            if (piece.col > this.col){
                dir[1] = 1;
            }else if (piece.col < this.col){
                dir[1] = -1;
            }
            return dir;
        }

        //随机游走
        private void moveRandom(){
            //获取所有相邻位置的空格
            List<int[]> emptyPositions = new ArrayList<>();
            if (this.row != 0) emptyPositions.add(new int[]{this.row-1, this.col});
            if (this.row != game.helper.getRowCount()-1) emptyPositions.add(new int[]{this.row+1, this.col});
            if (this.col != 0) emptyPositions.add(new int[]{this.row, this.col-1});
            if (this.col != game.helper.getColCount()-1) emptyPositions.add(new int[]{this.row, this.col+1});
            if (emptyPositions.size() > 0){
                int[] randomPosition = emptyPositions.get((int) (Math.random() * emptyPositions.size()));
                move(randomPosition[0], randomPosition[1]);
            }
        }

        @Override
        public String getInformation() {
            return "【怪物-丘林】\n" +
                    "生命值：" + this.hp + "\n" +
                    "攻击力：" + this.atk + "\n";
        }
    }

    /**
     * 棋子-怪物-暴徒
     */
    private static class MonsterBT extends BaseMonsterPiece implements IGameInformation{
        public MonsterBT(Game game, int row, int col) {
            super(game, "暴徒",row, col);
            this.hp = 20;
            this.atk = 10;
        }

        @Override
        public void updateSelf() {
            //玩家在攻击范围内，3/4的几率进行攻击
            if ( Math.random() < 0.75 && isAdjacentToPiece(game.human)){
                this.attack(game.human);
                return;
            }
            //玩家在视野范围内，优先朝着玩家移动
            if (isInView(game.human) && !isAdjacentToPiece(game.human)){
                int[] moveDir = getMoveDir(game.human);
                this.move(this.row + moveDir[0],  this.col + moveDir[1]);
                return;
            }
            //否则随机游走
            moveRandom();
        }

        //目标棋子在自己的视野范围内
        public boolean isInView(BasePiece piece){
            return game.helper.room.helper.getDistance(this.row,this.col, piece.row, piece.col) <= 6;
        }

        //根据目标棋子获取移动方向
        public int[] getMoveDir(BasePiece piece) {
            int[] dir = new int[]{0,0};
            if (piece.row > this.row){
                dir[0] = 1;
            }else if (piece.row < this.row){
                dir[0] = -1;
            }
            if (piece.col > this.col){
                dir[1] = 1;
            }else if (piece.col < this.col){
                dir[1] = -1;
            }
            return dir;
        }

        //随机游走
        private void moveRandom(){
            //获取所有相邻位置的空格
            List<int[]> emptyPositions = new ArrayList<>();
            for (int i = -1; i <= 1; i++) {
                for (int j = -1; j <= 1; j++) {
                    int newRow = row + i;
                    int newCol = col + j;
                    if ( newRow >= 0 && newRow < game.helper.room.curGrids.length && newCol >= 0 && newCol < game.helper.room.curGrids[0].length && game.helper.room.curGrids[newRow][newCol] == 0){
                        emptyPositions.add(new int[]{newRow, newCol});
                    }
                }
            }
            if (emptyPositions.size() > 0){
                int[] randomPosition = emptyPositions.get((int) (Math.random() * emptyPositions.size()));
                move(randomPosition[0], randomPosition[1]);
            }
        }

        @Override
        public String getInformation() {
            return "【怪物-暴徒】\n" +
                    "生命值：" + this.hp + "\n" +
                    "攻击力：" + this.atk + "\n";
        }
    }

    /**
     * 棋子-道具-墙
     */
    private static class PropWall extends BasePropPiece{

        public PropWall(Game game, String name, int row, int col) {
            super(game, "墙", row, col);
            this.getAble = false;
        }

        @Override
        public void renderSelf() {

        }
    }

    /**
     * 棋子-道具-苹果
     */
    private static class PropApple extends BasePropPiece implements IGameInformation{

        public PropApple(BWAntiSpaceOldRoom room, Game game, String name, int row, int col) {
            super(game, "苹果", row, col);
            this.getAble = true;
        }

        @Override
        public void renderSelf() {

        }

        @Override
        public String getInformation() {
            return "【道具-苹果】\n" +
                    "主角和怪物都能吃苹果，吃了苹果后能恢复10点生命值。";
        }
    }
}
